﻿using System;
using System.Diagnostics;
using System.Html.DOM;
using Knockout;

namespace Calculator
{
    [ImportClass("", "AppViewModel")]
    public class AppViewModel
    {
        public Observable<string> Result = Ko.Observable<string>("0");
        public Observable<string> Operator = Ko.Observable<string>("");
        public Observable<string> Register = Ko.Observable<string>("0");

        public Observable<bool> Has_error = Ko.Observable<bool>(false);

        public Observable<string> Anglemode = Ko.Observable<string>(Constant.DEG);
        public Observable<string> Radix = Ko.Observable<string>(Constant.DEC);
        public Observable<string> Memorymode = Ko.Observable<string>("");
        public Observable<string> Memorydata = Ko.Observable<string>("");

        public Observable<bool> Is_inv = Ko.Observable<bool>(false);
        public Observable<bool> Is_hyp = Ko.Observable<bool>(false);

        public Observable<bool> Function_enable = Ko.Computed<bool>(() =>
        {
            return KoX<AppViewModel>.SEFL.Radix() == Constant.DEC;
        });

        public Observable<int> Radix_number = Ko.Computed<int>(() =>
        {
            switch (KoX<AppViewModel>.SEFL.Radix())
            {
                case Constant.BIN:
                    return 2;
                case Constant.OCT:
                    return 8;
                case Constant.DEC:
                    return 10;
                case Constant.HEX:
                    return 16;
            }
            return 10;
        });

        private Core _core = new Core();
        public void NumberClick(object o, DomEvent e)
        {
            var text = e.CurrentTarget.InnerHTML;
            _core.InputNumber(text);
            this.Result(_core.Result);
        }

        public void DecimalClick()
        {
            _core.InputDecimal();
            this.Result(_core.Result);
        }

        public void OperatorClick(object o, DomEvent e)
        {
            var val = e.CurrentTarget.InnerHTML;
            _core.InputOperator(val);

            this.Operator(_core.Operator);
            this.Register(_core.Register);
            this.Result(_core.Result);
            this.Has_error(_core.HasError);
        }

        public void EqualClick()
        {
            _core.InputEqual();

            this.Operator(_core.Operator);
            this.Register(_core.Register);
            this.Result(_core.Result);
            this.Has_error(_core.HasError);
        }

        public void SignClick()
        {
            _core.InputSign();
            this.Result(_core.Result);
        }

        public void PercentClick()
        {
            _core.InputPercent();
            this.Result(_core.Result);
        }

        public void ResetClick()
        {
            _core.InputReset();
            this.Result(_core.Result);
            this.Register(_core.Register);
            this.Operator(_core.Operator);
            this.Has_error(_core.HasError);
        }

        public void BackClick()
        {
            _core.InputBack();
            this.Result(_core.Result);
        }

        public void ConstantClick(object o, DomEvent e)
        {
            var val = e.CurrentTarget.InnerHTML;
            _core.InputConstant(val);
            this.Result(_core.Result);
        }

        public void MemoryClick(object o, DomEvent e)
        {
            var val = e.CurrentTarget.InnerHTML;

            _core.InputMemory(val);

            this.Result(_core.Result);
            this.Memorymode(_core.HasMemory ? "M" : "");
            if (_core.HasMemory)
            {
                this.Memorydata(_core.MemoryData.ToString());
            }
            else
            {
                this.Memorydata("");
            }
        }

        public void Inv()
        {
            this.Is_inv(!Is_inv());
        }

        public void Hyp()
        {
            this.Is_hyp(!Is_hyp());
        }

        public void TrigonometricClick(object o, DomEvent e)
        {
            dynamic text = e.CurrentTarget.InnerHTML;
            string val = text.trim().substr(0, 3);
            _core.InputTrigonometric(val, this.Is_inv(), this.Is_hyp());
            this.Result(_core.Result);
            this.Has_error(_core.HasError);
            
            this.Is_inv(false);
        }

        public void FunctionClick(object o, DomEvent e)
        {
            string func = e.CurrentTarget.Dataset["function"] as string;
            _core.InputFunction(func);
            this.Result(_core.Result);
            this.Has_error(_core.HasError);
        }

        public void Anglemode_change(object o, DomEvent e)
        {
            var text = e.CurrentTarget.InnerHTML;
            this.Anglemode(text);
            _core.AngleMode = text;
            this.Result(_core.Result);
        }        

        public void Radix_change(object o, DomEvent e)
        {
            var text = e.CurrentTarget.InnerHTML;
            this.Radix(text);
            _core.Radix = this.Radix_number();
            this.Result(_core.Result);
            this.Operator(_core.Operator);
            this.Register(_core.Register);
        }
    }
}
